package com.apestech.framework.stream;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import com.apestech.framework.json.JSONObject;

public class WebStream {
	
	private ArrayObject list;
	private int fetchSize;
	private ArrayList<ByteArrayOutputStream> oslist=new ArrayList<ByteArrayOutputStream>();
	private int maxCount=-1;
	private int count=0;
	private boolean finish=false;
	private int pagesize=0;
	
	public WebStream(ArrayObject list){
		this.list=list;
	}
	
	public void setFetchSize(int fetchSize){
		this.fetchSize=fetchSize;
	}
	
	public void setCount(int count){
		this.count=count;
	}
	
	public int getPageCount(){
		return this.oslist.size();
	}
	
	public void setMaxCount(int maxCount){
		this.maxCount=maxCount;
	}
	
	public void setFirstData(byte[] b) throws Exception{
		ByteArrayOutputStream os=new ByteArrayOutputStream();
		os.write(b,0,b.length);
		this.oslist.add(os);
	}

	public boolean finish(){
		return this.finish;
	}
	
	public void write() throws Exception{
		while(this.list.next()){
			ByteArrayOutputStream os=getByteArrayOutputStream(count);
			if(os.size()>1){
				os.write(",".getBytes("UTF-8"));
			}
			JSONObject d=this.list.getJSON();
			os.write(this.list.getText().getBytes("UTF-8"));
			count++;
			if(this.maxCount>0 && count>this.maxCount){
				break;
			}
		}
		setLastOs();
		this.finish=true;
	}

	public void writeThread() throws Exception{
		ByteArrayOutputStream os=getByteArrayOutputStream(count);
		int i=count;
		while(i!=writeThread(os)){
			i=count;
			os=getByteArrayOutputStream(count);
			if(this.maxCount>0 && count>=this.maxCount){
				break;
			}
		}
		setLastOs();
		this.finish=true;
	}

	private int writeThread(ByteArrayOutputStream os) throws Exception{
		int i=0;
		while(this.list.next()){
			i++;
			if(os.size()>1){
				os.write(",".getBytes("UTF-8"));
			}
			JSONObject d=this.list.getJSON();
			os.write(this.list.getText().getBytes("UTF-8"));
			count++;
			if((i==this.fetchSize)||(this.maxCount>0 && count>this.maxCount)){
				break;
			}
		}
		return count;
	}

	private ByteArrayOutputStream getByteArrayOutputStream(int index) throws Exception{
		int pos=index/this.fetchSize;
		if(pos>=this.oslist.size()){
			setLastOs();
			ByteArrayOutputStream os=new ByteArrayOutputStream();
			os.write("[".getBytes("UTF-8"));
			this.oslist.add(os);
		}
		return this.oslist.get(pos);
	}
	
	private void setLastOs() throws UnsupportedEncodingException, IOException{
		if(this.oslist.size()==0) return;
		ByteArrayOutputStream os=this.oslist.get(this.oslist.size()-1);
		os.write("]".getBytes("UTF-8"));
		os.flush();
		this.pagesize=this.oslist.size();
	}
	
	public byte[] getData(int page) throws Exception{
		if(page>this.oslist.size()) return null;
		byte[] b=this.oslist.get(page-1).toByteArray();
		return b;
	}
	
	public void close() throws Exception{
		int len=this.oslist.size();
		for(int i=0; i<len; i++){
			this.oslist.get(i).close();
		}
	}

}
